home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 15 / CU Amiga Magazine's Super CD-ROM 15 (1997)(EMAP Images)(GB)[!][issue 1997-10].iso / CUCD / Graphics / Ghostscript / source / libpng / pngpread.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-12  |  30.3 KB  |  1,103 lines

  1.  
  2. /* pngpread.c - read a png file in push mode
  3.  
  4.    libpng 1.0 beta 6 - version 0.96
  5.    For conditions of distribution and use, see copyright notice in png.h
  6.    Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  7.    Copyright (c) 1996, 1997 Andreas Dilger
  8.    May 12, 1997
  9.    */
  10.  
  11. #define PNG_INTERNAL
  12. #include "png.h"
  13.  
  14. #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
  15.  
  16. void
  17. png_process_data(png_structp png_ptr, png_infop info_ptr,
  18.    png_bytep buffer, png_size_t buffer_size)
  19. {
  20.    png_push_restore_buffer(png_ptr, buffer, buffer_size);
  21.  
  22.    while (png_ptr->buffer_size)
  23.    {
  24.       png_process_some_data(png_ptr, info_ptr);
  25.    }
  26. }
  27.  
  28. /* What we do with the incoming data depends on what we were previously
  29.  * doing before we ran out of data...
  30.  */
  31. void
  32. png_process_some_data(png_structp png_ptr, png_infop info_ptr)
  33. {
  34.    switch (png_ptr->process_mode)
  35.    {
  36.       case PNG_READ_SIG_MODE:
  37.       {
  38.          png_push_read_sig(png_ptr, info_ptr);
  39.          break;
  40.       }
  41.       case PNG_READ_CHUNK_MODE:
  42.       {
  43.          png_push_read_chunk(png_ptr, info_ptr);
  44.          break;
  45.       }
  46.       case PNG_READ_IDAT_MODE:
  47.       {
  48.          png_push_read_IDAT(png_ptr);
  49.          break;
  50.       }
  51. #if defined(PNG_READ_tEXt_SUPPORTED)
  52.       case PNG_READ_tEXt_MODE:
  53.       {
  54.          png_push_read_tEXt(png_ptr, info_ptr);
  55.          break;
  56.       }
  57. #endif
  58. #if defined(PNG_READ_zTXt_SUPPORTED)
  59.       case PNG_READ_zTXt_MODE:
  60.       {
  61.          png_push_read_zTXt(png_ptr, info_ptr);
  62.          break;
  63.       }
  64. #endif
  65.       case PNG_SKIP_MODE:
  66.       {
  67.          png_push_crc_finish(png_ptr);
  68.          break;
  69.       }
  70.       default:
  71.       {
  72.          png_ptr->buffer_size = 0;
  73.          break;
  74.       }
  75.    }
  76. }
  77.  
  78. /* Read any remaining signature bytes from the stream and compare them with
  79.  * the correct PNG signature.  It is possible that this routine is called
  80.  * with bytes already read from the signature, whether because they have been
  81.  * checked by the calling application, or from multiple calls to this routine.
  82.  */
  83. void
  84. png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
  85. {
  86.    png_size_t num_checked = png_ptr->sig_bytes,
  87.              num_to_check = 8 - num_checked;
  88.  
  89.    if (png_ptr->buffer_size < num_to_check)
  90.    {
  91.       num_to_check = png_ptr->buffer_size;
  92.    }
  93.  
  94.    png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), 
  95.       num_to_check);
  96.    png_ptr->sig_bytes += num_to_check;
  97.  
  98.    if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
  99.    {
  100.       if (num_checked < 4 &&
  101.           png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
  102.          png_error(png_ptr, "Not a PNG file");
  103.       else
  104.          png_error(png_ptr, "PNG file corrupted by ASCII conversion");
  105.    }
  106.    else
  107.    {
  108.       if (png_ptr->sig_bytes >= 8)
  109.       {
  110.          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  111.       }
  112.    }
  113. }
  114.  
  115. void
  116. png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
  117. {
  118.    /* First we make sure we have enough data for the 4 byte chunk name
  119.       and the 4 byte chunk length before proceeding with decoding the
  120.       chunk data.  To fully decode each of these chunks, we also make
  121.       sure we have enough data in the buffer for the 4 byte CRC at the
  122.       end of every chunk (except IDAT, which is handled separately). */
  123.    if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER))
  124.    {
  125.       png_byte chunk_length[4];
  126.  
  127.       if (png_ptr->buffer_size < 8)
  128.       {
  129.          png_push_save_buffer(png_ptr);
  130.          return;
  131.       }
  132.  
  133.       png_push_fill_buffer(png_ptr, chunk_length, 4);
  134.       png_ptr->push_length = png_get_uint_32(chunk_length);
  135.       png_reset_crc(png_ptr);
  136.       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
  137.       png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
  138.    }
  139.  
  140.    if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
  141.    {
  142.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  143.       {
  144.          png_push_save_buffer(png_ptr);
  145.          return;
  146.       }
  147.  
  148.       png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
  149.    }
  150.    else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
  151.    {
  152.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  153.       {
  154.          png_push_save_buffer(png_ptr);
  155.          return;
  156.       }
  157.  
  158.       png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
  159.    }
  160.    else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  161.    {
  162.       /* If we reach an IDAT chunk, this means we have read all of the
  163.          header chunks, and we can start reading the image (or if this
  164.          is called after the image has been read - we have an error). */
  165.       if (png_ptr->mode & PNG_HAVE_IDAT)
  166.       {
  167.          if (png_ptr->push_length == 0)
  168.             return;
  169.  
  170.          if (png_ptr->mode & PNG_AFTER_IDAT)
  171.             png_error(png_ptr, "Too many IDAT's found");
  172.       }
  173.  
  174.       png_ptr->idat_size = png_ptr->push_length;
  175.       png_ptr->mode |= PNG_HAVE_IDAT;
  176.       png_ptr->process_mode = PNG_READ_IDAT_MODE;
  177.       png_push_have_info(png_ptr, info_ptr);
  178.       png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
  179.       png_ptr->zstream.next_out = png_ptr->row_buf;
  180.       return;
  181.    }
  182.    else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
  183.    {
  184.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  185.       {
  186.          png_push_save_buffer(png_ptr);
  187.          return;
  188.       }
  189.  
  190.       png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
  191.       png_ptr->process_mode = PNG_READ_DONE_MODE;
  192.       png_push_have_end(png_ptr, info_ptr);
  193.    }
  194. #if defined(PNG_READ_gAMA_SUPPORTED)
  195.    else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
  196.    {
  197.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  198.       {
  199.          png_push_save_buffer(png_ptr);
  200.          return;
  201.       }
  202.  
  203.       png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
  204.    }
  205. #endif
  206. #if defined(PNG_READ_sBIT_SUPPORTED)
  207.    else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
  208.    {
  209.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  210.       {
  211.          png_push_save_buffer(png_ptr);
  212.          return;
  213.       }
  214.  
  215.       png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
  216.    }
  217. #endif
  218. #if defined(PNG_READ_cHRM_SUPPORTED)
  219.    else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
  220.    {
  221.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  222.       {
  223.          png_push_save_buffer(png_ptr);
  224.          return;
  225.       }
  226.  
  227.       png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
  228.    }
  229. #endif
  230. #if defined(PNG_READ_tRNS_SUPPORTED)
  231.    else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
  232.    {
  233.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  234.       {
  235.          png_push_save_buffer(png_ptr);
  236.          return;
  237.       }
  238.  
  239.       png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
  240.    }
  241. #endif
  242. #if defined(PNG_READ_bKGD_SUPPORTED)
  243.    else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
  244.    {
  245.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  246.       {
  247.          png_push_save_buffer(png_ptr);
  248.          return;
  249.       }
  250.  
  251.       png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
  252.    }
  253. #endif
  254. #if defined(PNG_READ_hIST_SUPPORTED)
  255.    else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
  256.    {
  257.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  258.       {
  259.          png_push_save_buffer(png_ptr);
  260.          return;
  261.       }
  262.  
  263.       png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
  264.    }
  265. #endif
  266. #if defined(PNG_READ_pHYs_SUPPORTED)
  267.    else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
  268.    {
  269.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  270.       {
  271.          png_push_save_buffer(png_ptr);
  272.          return;
  273.       }
  274.  
  275.       png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
  276.    }
  277. #endif
  278. #if defined(PNG_READ_oFFs_SUPPORTED)
  279.    else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
  280.    {
  281.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  282.       {
  283.          png_push_save_buffer(png_ptr);
  284.          return;
  285.       }
  286.  
  287.       png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
  288.    }
  289. #endif
  290. #if defined(PNG_READ_pCAL_SUPPORTED)
  291.    else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
  292.    {
  293.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  294.       {
  295.          png_push_save_buffer(png_ptr);
  296.          return;
  297.       }
  298.  
  299.       png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
  300.    }
  301. #endif
  302. #if defined(PNG_READ_tIME_SUPPORTED)
  303.    else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
  304.    {
  305.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  306.       {
  307.          png_push_save_buffer(png_ptr);
  308.          return;
  309.       }
  310.  
  311.       png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
  312.    }
  313. #endif
  314. #if defined(PNG_READ_tEXt_SUPPORTED)
  315.    else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
  316.    {
  317.       png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
  318.    }
  319. #endif
  320. #if defined(PNG_READ_zTXt_SUPPORTED)
  321.    else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
  322.    {
  323.       png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
  324.    }
  325. #endif
  326.    else
  327.    {
  328.       png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
  329.    }
  330.  
  331.    png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER;
  332. }
  333.  
  334. void
  335. png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
  336. {
  337.    png_ptr->process_mode = PNG_SKIP_MODE;
  338.    png_ptr->skip_length = skip;
  339. }
  340.  
  341. void
  342. png_push_crc_finish(png_structp png_ptr)
  343. {
  344.    if (png_ptr->skip_length && png_ptr->save_buffer_size)
  345.    {
  346.       png_size_t save_size;
  347.  
  348.       if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
  349.          save_size = (png_size_t)png_ptr->skip_length;
  350.       else
  351.          save_size = png_ptr->save_buffer_size;
  352.  
  353.       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
  354.  
  355.       png_ptr->skip_length -= save_size;
  356.       png_ptr->buffer_size -= save_size;
  357.       png_ptr->save_buffer_size -= save_size;
  358.       png_ptr->save_buffer_ptr += save_size;
  359.    }
  360.    if (png_ptr->skip_length && png_ptr->current_buffer_size)
  361.    {
  362.       png_size_t save_size;
  363.  
  364.       if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
  365.          save_size = (png_size_t)png_ptr->skip_length;
  366.       else
  367.          save_size = png_ptr->current_buffer_size;
  368.  
  369.       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
  370.  
  371.       png_ptr->skip_length -= save_size;
  372.       png_ptr->buffer_size -= save_size;
  373.       png_ptr->current_buffer_size -= save_size;
  374.       png_ptr->current_buffer_ptr += save_size;
  375.    }
  376.    if (!png_ptr->skip_length)
  377.    {
  378.       if (png_ptr->buffer_size < 4)
  379.       {
  380.          png_push_save_buffer(png_ptr);
  381.          return;
  382.       }
  383.  
  384.       png_crc_finish(png_ptr, 0);
  385.       png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  386.    }
  387. }
  388.  
  389. void
  390. png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
  391. {
  392.    png_bytep ptr;
  393.  
  394.    ptr = buffer;
  395.    if (png_ptr->save_buffer_size)
  396.    {
  397.       png_size_t save_size;
  398.  
  399.       if (length < png_ptr->save_buffer_size)
  400.          save_size = length;
  401.       else
  402.          save_size = png_ptr->save_buffer_size;
  403.  
  404.       png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
  405.       length -= save_size;
  406.       ptr += save_size;
  407.       png_ptr->buffer_size -= save_size;
  408.       png_ptr->save_buffer_size -= save_size;
  409.       png_ptr->save_buffer_ptr += save_size;
  410.    }
  411.    if (length && png_ptr->current_buffer_size)
  412.    {
  413.       png_size_t save_size;
  414.  
  415.       if (length < png_ptr->current_buffer_size)
  416.          save_size = length;
  417.       else
  418.          save_size = png_ptr->current_buffer_size;
  419.  
  420.       png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
  421.       png_ptr->buffer_size -= save_size;
  422.       png_ptr->current_buffer_size -= save_size;
  423.       png_ptr->current_buffer_ptr += save_size;
  424.    }
  425. }
  426.  
  427. void
  428. png_push_save_buffer(png_structp png_ptr)
  429. {
  430.    if (png_ptr->save_buffer_size)
  431.    {
  432.       if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
  433.       {
  434.          png_size_t i;
  435.          png_bytep sp;
  436.          png_bytep dp;
  437.  
  438.          for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
  439.             i < png_ptr->save_buffer_size;
  440.             i++, sp++, dp++)
  441.          {
  442.             *dp = *sp;
  443.          }
  444.       }
  445.    }
  446.    if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
  447.       png_ptr->save_buffer_max)
  448.    {
  449.       png_size_t new_max;
  450.       png_bytep old_buffer;
  451.  
  452.       new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
  453.       old_buffer = png_ptr->save_buffer;
  454.       png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr, new_max);
  455.       png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
  456.       png_free(png_ptr, old_buffer);
  457.       png_ptr->save_buffer_max = new_max;
  458.    }
  459.    if (png_ptr->current_buffer_size)
  460.    {
  461.       png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
  462.          png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
  463.       png_ptr->save_buffer_size += png_ptr->current_buffer_size;
  464.       png_ptr->current_buffer_size = 0;
  465.    }
  466.    png_ptr->save_buffer_ptr = png_ptr->save_buffer;
  467.    png_ptr->buffer_size = 0;
  468. }
  469.  
  470. void
  471. png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
  472.    png_size_t buffer_length)
  473. {
  474.    png_ptr->current_buffer = buffer;
  475.    png_ptr->current_buffer_size = buffer_length;
  476.    png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
  477.    png_ptr->current_buffer_ptr = png_ptr->current_buffer;
  478. }
  479.  
  480. void
  481. png_push_read_IDAT(png_structp png_ptr)
  482. {
  483.    if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER))
  484.    {
  485.       png_byte chunk_length[4];
  486.  
  487.       if (png_ptr->buffer_size < 8)
  488.       {
  489.          png_push_save_buffer(png_ptr);
  490.          return;
  491.       }
  492.  
  493.       png_push_fill_buffer(png_ptr, chunk_length, 4);
  494.       png_ptr->push_length = png_get_uint_32(chunk_length);
  495.  
  496.       png_reset_crc(png_ptr);
  497.       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
  498.       png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
  499.  
  500.       if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  501.       {
  502.          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  503.          if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
  504.             png_error(png_ptr, "Not enough compressed data");
  505.          return;
  506.       }
  507.  
  508.       png_ptr->idat_size = png_ptr->push_length;
  509.    }
  510.    if (png_ptr->idat_size && png_ptr->save_buffer_size)
  511.    {
  512.       png_size_t save_size;
  513.  
  514.       if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
  515.          save_size = png_ptr->idat_size;
  516.       else
  517.          save_size = png_ptr->save_buffer_size;
  518.  
  519.       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
  520.       png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
  521.  
  522.       png_ptr->idat_size -= save_size;
  523.       png_ptr->buffer_size -= save_size;
  524.       png_ptr->save_buffer_size -= save_size;
  525.       png_ptr->save_buffer_ptr += save_size;
  526.    }
  527.    if (png_ptr->idat_size && png_ptr->current_buffer_size)
  528.    {
  529.       png_size_t save_size;
  530.  
  531.       if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
  532.          save_size = png_ptr->idat_size;
  533.       else
  534.          save_size = png_ptr->current_buffer_size;
  535.  
  536.       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
  537.       png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
  538.  
  539.       png_ptr->idat_size -= save_size;
  540.       png_ptr->buffer_size -= save_size;
  541.       png_ptr->current_buffer_size -= save_size;
  542.       png_ptr->current_buffer_ptr += save_size;
  543.    }
  544.    if (!png_ptr->idat_size)
  545.    {
  546.       if (png_ptr->buffer_size < 4)
  547.       {
  548.          png_push_save_buffer(png_ptr);
  549.          return;
  550.       }
  551.  
  552.       png_crc_finish(png_ptr, 0);
  553.       png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER;
  554.    }
  555. }
  556.  
  557. void
  558. png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
  559.    png_size_t buffer_length)
  560. {
  561.    int ret;
  562.  
  563.    if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
  564.       png_error(png_ptr, "Extra compression data");
  565.  
  566.    png_ptr->zstream.next_in = buffer;
  567.    png_ptr->zstream.avail_in = (uInt)buffer_length;
  568.    while(1)
  569.    {
  570.       ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
  571.       if (ret == Z_STREAM_END)
  572.       {
  573.          if (png_ptr->zstream.avail_in)
  574.             png_error(png_ptr, "Extra compressed data");
  575.          if (!(png_ptr->zstream.avail_out))
  576.          {
  577.             png_push_process_row(png_ptr);
  578.          }
  579.  
  580.          png_ptr->mode |= PNG_AFTER_IDAT;
  581.          png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
  582.          break;
  583.       }
  584.       else if (ret == Z_BUF_ERROR)
  585.          break;
  586.       else if (ret != Z_OK)
  587.          png_error(png_ptr, "Decompression Error");
  588.       if (!(png_ptr->zstream.avail_out))
  589.       {
  590.          png_push_process_row(png_ptr);
  591.          png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
  592.          png_ptr->zstream.next_out = png_ptr->row_buf;
  593.       }
  594.       else
  595.          break;
  596.    }
  597. }
  598.  
  599. void
  600. png_push_process_row(png_structp png_ptr)
  601. {
  602.    png_ptr->row_info.color_type = png_ptr->color_type;
  603.    png_ptr->row_info.width = png_ptr->iwidth;
  604.    png_ptr->row_info.channels = png_ptr->channels;
  605.    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
  606.    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
  607.    png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
  608.       (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
  609.  
  610.    png_read_filter_row(png_ptr, &(png_ptr->row_info),
  611.       png_ptr->row_buf + 1, png_ptr->prev_row + 1,
  612.       (int)(png_ptr->row_buf[0]));
  613.  
  614.    png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1);
  615.  
  616.    if (png_ptr->transformations)
  617.       png_do_read_transformations(png_ptr);
  618.  
  619. #if defined(PNG_READ_INTERLACING_SUPPORTED)
  620.    /* blow up interlaced rows to full size */
  621.    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
  622.    {
  623.       if (png_ptr->pass < 6)
  624.          png_do_read_interlace(&(png_ptr->row_info),
  625.             png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
  626.  
  627.       switch (png_ptr->pass)
  628.       {
  629.          case 0:
  630.          {
  631.             int i;
  632.             for (i = 0; i < 8 && png_ptr->pass == 0; i++)
  633.             {
  634.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  635.                png_read_push_finish_row(png_ptr);
  636.             }
  637.             break;
  638.          }
  639.          case 1:
  640.          {
  641.             int i;
  642.             for (i = 0; i < 8 && png_ptr->pass == 1; i++)
  643.             {
  644.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  645.                png_read_push_finish_row(png_ptr);
  646.             }
  647.             if (png_ptr->pass == 2)
  648.             {
  649.                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  650.                {
  651.                   png_push_have_row(png_ptr, NULL);
  652.                   png_read_push_finish_row(png_ptr);
  653.                }
  654.             }
  655.             break;
  656.          }
  657.          case 2:
  658.          {
  659.             int i;
  660.             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  661.             {
  662.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  663.                png_read_push_finish_row(png_ptr);
  664.             }
  665.             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  666.             {
  667.                png_push_have_row(png_ptr, NULL);
  668.                png_read_push_finish_row(png_ptr);
  669.             }
  670.             break;
  671.          }
  672.          case 3:
  673.          {
  674.             int i;
  675.             for (i = 0; i < 4 && png_ptr->pass == 3; i++)
  676.             {
  677.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  678.                png_read_push_finish_row(png_ptr);
  679.             }
  680.             if (png_ptr->pass == 4)
  681.             {
  682.                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  683.                {
  684.                   png_push_have_row(png_ptr, NULL);
  685.                   png_read_push_finish_row(png_ptr);
  686.                }
  687.             }
  688.             break;
  689.          }
  690.          case 4:
  691.          {
  692.             int i;
  693.             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  694.             {
  695.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  696.                png_read_push_finish_row(png_ptr);
  697.             }
  698.             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  699.             {
  700.                png_push_have_row(png_ptr, NULL);
  701.                png_read_push_finish_row(png_ptr);
  702.             }
  703.             break;
  704.          }
  705.          case 5:
  706.          {
  707.             int i;
  708.             for (i = 0; i < 2 && png_ptr->pass == 5; i++)
  709.             {
  710.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  711.                png_read_push_finish_row(png_ptr);
  712.             }
  713.             if (png_ptr->pass == 6)
  714.             {
  715.                png_push_have_row(png_ptr, NULL);
  716.                png_read_push_finish_row(png_ptr);
  717.             }
  718.             break;
  719.          }
  720.          case 6:
  721.          {
  722.             png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  723.             png_read_push_finish_row(png_ptr);
  724.             if (png_ptr->pass != 6)
  725.                break;
  726.             png_push_have_row(png_ptr, NULL);
  727.             png_read_push_finish_row(png_ptr);
  728.          }
  729.       }
  730.    }
  731.    else
  732. #endif
  733.    {
  734.       png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  735.       png_read_push_finish_row(png_ptr);
  736.    }
  737. }
  738.  
  739. void
  740. png_read_push_finish_row(png_structp png_ptr)
  741. {
  742.    png_ptr->row_number++;
  743.    if (png_ptr->row_number < png_ptr->num_rows)
  744.       return;
  745.  
  746.    if (png_ptr->interlaced)
  747.    {
  748.       png_ptr->row_number = 0;
  749.       png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
  750.       do
  751.       {
  752.          png_ptr->pass++;
  753.          if (png_ptr->pass >= 7)
  754.             break;
  755.          png_ptr->iwidth = (png_ptr->width +
  756.             png_pass_inc[png_ptr->pass] - 1 -
  757.             png_pass_start[png_ptr->pass]) /
  758.             png_pass_inc[png_ptr->pass];
  759.          png_ptr->irowbytes = ((png_ptr->iwidth *
  760.             png_ptr->pixel_depth + 7) >> 3) + 1;
  761.          if (!(png_ptr->transformations & PNG_INTERLACE))
  762.          {
  763.             png_ptr->num_rows = (png_ptr->height +
  764.                png_pass_yinc[png_ptr->pass] - 1 -
  765.                png_pass_ystart[png_ptr->pass]) /
  766.                png_pass_yinc[png_ptr->pass];
  767.             if (!(png_ptr->num_rows))
  768.                continue;
  769.          }
  770.          if (png_ptr->transformations & PNG_INTERLACE)
  771.             break;
  772.       } while (png_ptr->iwidth == 0);
  773.    }
  774. }
  775.  
  776. #if defined(PNG_READ_tEXt_SUPPORTED)
  777. void
  778. png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  779. {
  780.    if (png_ptr->mode == PNG_BEFORE_IHDR || png_ptr->mode & PNG_HAVE_IEND)
  781.       png_error(png_ptr, "Out of place tEXt");
  782.  
  783. #ifdef PNG_MAX_MALLOC_64K
  784.    png_ptr->skip_length = 0;  /* This may not be necessary */
  785.  
  786.    if (length > 65535L)  /* We can't hold the entire string in memory */
  787.    {
  788.       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
  789.       png_ptr->skip_length = length - 65535L;
  790.       length = 65535L;
  791.    }
  792. #endif
  793.  
  794.    png_ptr->current_text = (png_charp)png_malloc(png_ptr, length+1);
  795.    png_ptr->current_text[length] = '\0';
  796.    png_ptr->current_text_ptr = png_ptr->current_text;
  797.    png_ptr->current_text_size = length;
  798.    png_ptr->current_text_left = length;
  799.    png_ptr->process_mode = PNG_READ_tEXt_MODE;
  800. }
  801.  
  802. void
  803. png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
  804. {
  805.    if (png_ptr->buffer_size && png_ptr->current_text_left)
  806.    {
  807.       png_size_t text_size;
  808.  
  809.       if (png_ptr->buffer_size < png_ptr->current_text_left)
  810.          text_size = png_ptr->buffer_size;
  811.       else
  812.          text_size = png_ptr->current_text_left;
  813.       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
  814.       png_ptr->current_text_left -= text_size;
  815.       png_ptr->current_text_ptr += text_size;
  816.    }
  817.    if (!(png_ptr->current_text_left))
  818.    {
  819.       png_textp text_ptr;
  820.       png_charp text;
  821.       png_charp key;
  822.  
  823.       if (png_ptr->buffer_size < 4)
  824.       {
  825.          png_push_save_buffer(png_ptr);
  826.          return;
  827.       }
  828.  
  829.       png_push_crc_finish(png_ptr);
  830.  
  831. #if defined(PNG_MAX_MALLOC_64K)
  832.       if (png_ptr->skip_length)
  833.          return;
  834. #endif
  835.  
  836.       key = png_ptr->current_text;
  837.       png_ptr->current_text = 0;
  838.  
  839.       for (text = key; *text; text++)
  840.          /* empty loop */ ;
  841.  
  842.       if (text != key + png_ptr->current_text_size)
  843.          text++;
  844.  
  845.       text_ptr = (png_textp)png_malloc(png_ptr, sizeof(png_text));
  846.       text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
  847.       text_ptr->key = key;
  848.       text_ptr->text = text;
  849.  
  850.       png_set_text(png_ptr, info_ptr, text_ptr, 1);
  851.  
  852.       png_free(png_ptr, text_ptr);
  853.    }
  854. }
  855. #endif
  856.  
  857. #if defined(PNG_READ_zTXt_SUPPORTED)
  858. void
  859. png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  860. {
  861.    if (png_ptr->mode == PNG_BEFORE_IHDR || png_ptr->mode & PNG_HAVE_IEND)
  862.       png_error(png_ptr, "Out of place zTXt");
  863.  
  864. #ifdef PNG_MAX_MALLOC_64K
  865.    /* We can't handle zTXt chunks > 64K, since we don't have enough space
  866.     * to be able to store the uncompressed data.  Actually, the threshold
  867.     * is probably around 32K, but it isn't as definite as 64K is.
  868.     */
  869.    if (length > 65535L)
  870.    {
  871.       png_warning(png_ptr, "zTXt chunk too large to fit in memory");
  872.       png_push_crc_skip(png_ptr, length);
  873.       return;
  874.    }
  875. #endif
  876.  
  877.    png_ptr->current_text = (png_charp)png_malloc(png_ptr, length+1);
  878.    png_ptr->current_text[length] = '\0';
  879.    png_ptr->current_text_ptr = png_ptr->current_text;
  880.    png_ptr->current_text_size = length;
  881.    png_ptr->current_text_left = length;
  882.    png_ptr->process_mode = PNG_READ_zTXt_MODE;
  883. }
  884.  
  885. void
  886. png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
  887. {
  888.    if (png_ptr->buffer_size && png_ptr->current_text_left)
  889.    {
  890.       png_size_t text_size;
  891.  
  892.       if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
  893.          text_size = png_ptr->buffer_size;
  894.       else
  895.          text_size = png_ptr->current_text_left;
  896.       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
  897.       png_ptr->current_text_left -= text_size;
  898.       png_ptr->current_text_ptr += text_size;
  899.    }
  900.    if (!(png_ptr->current_text_left))
  901.    {
  902.       png_textp text_ptr;
  903.       png_charp text;
  904.       png_charp key;
  905.       int ret;
  906.       png_size_t text_size, key_size;
  907.  
  908.       if (png_ptr->buffer_size < 4)
  909.       {
  910.          png_push_save_buffer(png_ptr);
  911.          return;
  912.       }
  913.  
  914.       png_push_crc_finish(png_ptr);
  915.  
  916.       key = png_ptr->current_text;
  917.       png_ptr->current_text = 0;
  918.  
  919.       for (text = key; *text; text++)
  920.          /* empty loop */ ;
  921.  
  922.       /* zTXt can't have zero text */
  923.       if (text == key + png_ptr->current_text_size)
  924.       {
  925.          png_free(png_ptr, key);
  926.          return;
  927.       }
  928.  
  929.       text++;
  930.  
  931.       if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
  932.       {
  933.          png_free(png_ptr, key);
  934.          return;
  935.       }
  936.  
  937.       text++;
  938.  
  939.       png_ptr->zstream.next_in = (png_bytep )text;
  940.       png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
  941.          (text - key));
  942.       png_ptr->zstream.next_out = png_ptr->zbuf;
  943.       png_ptr->zstream.avail_out = png_ptr->zbuf_size;
  944.  
  945.       key_size = text - key;
  946.       text_size = 0;
  947.       text = NULL;
  948.       ret = Z_STREAM_END;
  949.  
  950.       while (png_ptr->zstream.avail_in)
  951.       {
  952.          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
  953.          if (ret != Z_OK && ret != Z_STREAM_END)
  954.          {
  955.             inflateReset(&png_ptr->zstream);
  956.             png_ptr->zstream.avail_in = 0;
  957.             png_free(png_ptr, key);
  958.             png_free(png_ptr, text);
  959.             return;
  960.          }
  961.          if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
  962.          {
  963.             if (text == NULL)
  964.             {
  965.                text = (png_charp)png_malloc(png_ptr,
  966.                   png_ptr->zbuf_size - png_ptr->zstream.avail_out +
  967.                      key_size + 1);
  968.                png_memcpy(text + key_size, png_ptr->zbuf,
  969.                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
  970.                png_memcpy(text, key, key_size);
  971.                text_size = key_size + png_ptr->zbuf_size -
  972.                   png_ptr->zstream.avail_out;
  973.                *(text + text_size) = '\0';
  974.             }
  975.             else
  976.             {
  977.                png_charp tmp;
  978.  
  979.                tmp = text;
  980.                text = png_malloc(png_ptr, text_size +
  981.                   png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1);
  982.                png_memcpy(text, tmp, text_size);
  983.                png_free(png_ptr, tmp);
  984.                png_memcpy(text + text_size, png_ptr->zbuf,
  985.                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
  986.                text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
  987.                *(text + text_size) = '\0';
  988.             }
  989.             if (ret != Z_STREAM_END)
  990.             {
  991.                png_ptr->zstream.next_out = png_ptr->zbuf;
  992.                png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  993.             }
  994.          }
  995.          else
  996.          {
  997.             break;
  998.          }
  999.  
  1000.          if (ret == Z_STREAM_END)
  1001.             break;
  1002.       }
  1003.  
  1004.       inflateReset(&png_ptr->zstream);
  1005.       png_ptr->zstream.avail_in = 0;
  1006.  
  1007.       if (ret != Z_STREAM_END)
  1008.       {
  1009.          png_free(png_ptr, key);
  1010.          png_free(png_ptr, text);
  1011.          return;
  1012.       }
  1013.  
  1014.       png_free(png_ptr, key);
  1015.       key = text;
  1016.       text += key_size;
  1017.       text_size -= key_size;
  1018.  
  1019.       text_ptr = (png_textp)png_malloc(png_ptr, sizeof(png_text));
  1020.       text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
  1021.       text_ptr->key = key;
  1022.       text_ptr->text = text;
  1023.  
  1024.       png_set_text(png_ptr, info_ptr, text_ptr, 1);
  1025.  
  1026.       png_free(png_ptr, text_ptr);
  1027.    }
  1028. }
  1029. #endif
  1030.  
  1031. /* This function is called when we haven't found a handler for this
  1032.    chunk.  In the future we will have code here which can handle
  1033.    user-defined callback functions for unknown chunks before they are
  1034.    ignored or cause an error.  If there isn't a problem with the
  1035.    chunk itself (ie a bad chunk name or a critical chunk), the chunk
  1036.    is (currently) silently ignored. */
  1037. void
  1038. png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1039. {
  1040.    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
  1041.  
  1042.    if (!(png_ptr->chunk_name[0] & 0x20))
  1043.    {
  1044.       char msg[40];
  1045.  
  1046.       sprintf(msg, "Unknown critical chunk %s", png_ptr->chunk_name);
  1047.       png_error(png_ptr, msg);
  1048.    }
  1049.  
  1050.    png_push_crc_skip(png_ptr, length);
  1051. }
  1052.  
  1053. void
  1054. png_push_have_info(png_structp png_ptr, png_infop info_ptr)
  1055. {
  1056.    if (png_ptr->info_fn != NULL)
  1057.       (*(png_ptr->info_fn))(png_ptr, info_ptr);
  1058. }
  1059.  
  1060. void
  1061. png_push_have_end(png_structp png_ptr, png_infop info_ptr)
  1062. {
  1063.    if (png_ptr->end_fn != NULL)
  1064.       (*(png_ptr->end_fn))(png_ptr, info_ptr);
  1065. }
  1066.  
  1067. void
  1068. png_push_have_row(png_structp png_ptr, png_bytep row)
  1069. {
  1070.    if (png_ptr->row_fn != NULL)
  1071.       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
  1072.          (int)png_ptr->pass);
  1073. }
  1074.  
  1075. void
  1076. png_progressive_combine_row (png_structp png_ptr,
  1077.    png_bytep old_row, png_bytep new_row)
  1078. {
  1079.    if (new_row != NULL)
  1080.       png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
  1081. }
  1082.  
  1083. void
  1084. png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
  1085.    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
  1086.    png_progressive_end_ptr end_fn)
  1087. {
  1088.    png_ptr->info_fn = info_fn;
  1089.    png_ptr->row_fn = row_fn;
  1090.    png_ptr->end_fn = end_fn;
  1091.  
  1092.    png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
  1093. }
  1094.  
  1095. png_voidp
  1096. png_get_progressive_ptr(png_structp png_ptr)
  1097. {
  1098.    return png_ptr->io_ptr;
  1099. }
  1100.  
  1101. #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
  1102.  
  1103.